package cn.easyplatform.studio.web.views.impl;

import cn.easyplatform.entities.beans.page.BindVariable;
import cn.easyplatform.entities.beans.project.ProjectBean;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.studio.StudioApp;
import cn.easyplatform.studio.cmd.entity.QueryModelCmd;
import cn.easyplatform.studio.context.Contexts;
import cn.easyplatform.studio.utils.WebUtils;
import cn.easyplatform.studio.vos.EntityVo;
import cn.easyplatform.studio.web.editors.EditorCallback;
import cn.easyplatform.type.EntityType;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.*;

import java.util.ArrayList;
import java.util.List;

public class BindVariableView extends AbstractView<List<BindVariable>> {
    private Borderlayout borderLayout;
    private Listbox listbox;

    private List<BindVariable> bindVariables;
    private boolean isChange = false;
    protected BindVariableView(Component component, EditorCallback<List<BindVariable>> cb) {
        super(component, cb);
        this.bindVariables = new ArrayList<>();
        if (cb.getValue() != null && cb.getValue().size() > 0) {
            for (BindVariable bindVariable: cb.getValue()) {
                BindVariable variable = new BindVariable();
                variable.setName(bindVariable.getName());
                variable.setDesp(bindVariable.getDesp());
                variable.setRef(bindVariable.getRef());
                variable.setDsId(bindVariable.getDsId());
                this.bindVariables.add(variable);
            }
        }
    }

    @Override
    protected void createContent(Component parent) {
        borderLayout = new Borderlayout();
        North north = new North();
        north.setSize("38px");
        north.setHflex("1");
        north.setBorder("none");
        north.setParent(borderLayout);

        Hlayout northDiv = new Hlayout();
        northDiv.setVflex("1");
        northDiv.setHflex("1");
        northDiv.setParent(north);

        String[] iconSclass = new String[]{"z-icon-plus", "z-icon-minus"};
        String[] label = new String[]{"bindVar.add.title", "bindVar.delete.title"};
        String[] id = new String[]{"addField", "deleteField"};
        for (int index = 0; index < iconSclass.length; index++) {
            A field = new A();
            field.setIconSclass(iconSclass[index]);
            field.setLabel(Labels.getLabel(label[index]));
            field.setSclass("btn btn-light btn-sm");
            field.setId(id[index]);
            field.addEventListener(Events.ON_CLICK, this);
            field.setParent(northDiv);
        }

        Center center = new Center();
        center.setHflex("1");
        center.setVflex("1");
        center.setBorder("none");
        center.setParent(borderLayout);

        listbox = new Listbox();
        listbox.setHflex("1");
        listbox.setVflex("1");
        listbox.setCheckmark(true);
        listbox.setOddRowSclass("none");
        listbox.setMold("paging");
        listbox.getPagingChild().setMold("os");
        listbox.setParent(center);

        Listhead listhead = new Listhead();
        listhead.setSizable(true);
        listhead.setParent(listbox);

        Listheader selectedHeader = new Listheader();
        selectedHeader.setWidth("25px");
        selectedHeader.setParent(listhead);
        String[] labels = new String[]{"bindVar.name.title", "entity.desp", "entity.table.db", "editor.report.content"};
        for (int index = 0; index < labels.length; index++) {
            Listheader listheader = new Listheader();
            listheader.setLabel(Labels.getLabel(labels[index]) + (index == 0 ? "*":""));
            listheader.setHflex("1");
            listheader.setParent(listhead);
        }

        if (bindVariables.size() > 0) {
            for (int index = 0; index < bindVariables.size(); index++) {
                createVar(bindVariables.get(index));
            }
        }
        South south = new South();
        south.setSize("44px");
        south.setHflex("1");
        south.setBorder("none");
        south.setParent(borderLayout);

        Div southDiv = new Div();
        southDiv.setParent(south);

        Button save = new Button(Labels.getLabel("button.save"));
        save.setIconSclass("z-icon-save");
        save.setSclass("pull-right epstudio-top");
        save.setId("save");
        save.addEventListener(Events.ON_CLICK, this);
        save.setParent(southDiv);

        borderLayout.setParent(parent);
    }

    @Override
    public void onEvent(Event event) throws Exception {
        if (event.getTarget().getId().equals("addField")) {
            BindVariable bindVariable = new BindVariable();
            if (bindVariables == null)
                bindVariables = new ArrayList<>();
            bindVariables.add(bindVariable);
            Listitem row = createVar(bindVariable);
            listbox.setActivePage(row);
            isChange = true;
        } else if (event.getTarget().getId().equals("deleteField")) {
            if (listbox.getSelectedItem() != null)
                WebUtils.showConfirm(Labels.getLabel("button.delete"), this);
            else
                WebUtils.showError(Labels.getLabel("action.selected.error"));
        } else if (event.getName().equals(Events.ON_OK)) {// 删除栏位
            BindVariable bindVariable = listbox.getSelectedItem().getValue();
            bindVariables.remove(bindVariable);
            listbox.getSelectedItem().detach();
            isChange = true;
        } else if (event.getTarget().getId().equals("save")) {
            if (isChange == false) {
                cb.setValue(bindVariables);
                borderLayout.getRoot().detach();
                onCloseClick(win);
            }
            else
                save();
        }
    }

    private void save() {
        Boolean nameIsBlank = false;
        Boolean refIsBlank = false;
        Boolean nameIsDouble = false;
        List<String> names = new ArrayList<>();
        for (BindVariable bindVariable : bindVariables) {
            if (Strings.isBlank(bindVariable.getName())) {
                nameIsBlank = true;
                break;
            } else if (Strings.isBlank(bindVariable.getRef())) {
                refIsBlank = true;
                break;
            }
            if (names.contains(bindVariable.getName())) {
                nameIsDouble = true;
                break;
            } else
                names.add(bindVariable.getName());
        }
        if (nameIsBlank == true) {
            WebUtils.showError(Labels.getLabel("message.no.empty", new Object[]{Labels.getLabel("bindVar.name.title")}));
        }/* else if (refIsBlank == true) {
            WebUtils.showError(Labels.getLabel("message.no.empty", new Object[]{Labels.getLabel("editor.report.content")}));
        } */else  if (nameIsDouble == true) {
            WebUtils.showError(Labels.getLabel("bindVar.name.noDouble"));
        } else {
            cb.setValue(bindVariables);
            borderLayout.getRoot().detach();
            onCloseClick(win);
        }
    }

    private Listitem createVar(BindVariable var) {
        Listitem li = new Listitem();
        li.setValue(var);
        li.appendChild(new Listcell());

        Listcell idCell = new Listcell();
        li.appendChild(idCell);
        Textbox idTextbox = new Textbox();
        idTextbox.setHflex("1");
        idTextbox.setValue(var.getName());
        idCell.appendChild(idTextbox);

        Listcell despCell = new Listcell();
        li.appendChild(despCell);
        Textbox despTextbox = new Textbox();
        despTextbox.setHflex("1");
        despTextbox.setValue(var.getDesp());
        despCell.appendChild(despTextbox);

        Listcell dsIdCell = new Listcell();
        li.appendChild(dsIdCell);
        Combobox dsIdCombobox = new Combobox();
        dsIdCombobox.setHflex("1");
        dsIdCombobox.setReadonly(true);
        List<EntityVo> ds = StudioApp.execute(new QueryModelCmd(
                EntityType.DATASOURCE.getName()));
        ProjectBean pb = Contexts.getProject();
        for (EntityVo vo : ds) {
            Comboitem ci = new Comboitem(vo.getId());
            ci.setDescription(vo.getName());
            ci.setValue(vo.getId());
            dsIdCombobox.appendChild(ci);
            if (pb.getBizDb().equals(vo.getId()))
                dsIdCombobox.setSelectedItem(ci);
        }
        dsIdCell.appendChild(dsIdCombobox);

        Listcell refCell = new Listcell();
        li.appendChild(refCell);
        Textbox refTextbox = new Textbox();
        refTextbox.setHflex("1");
        refTextbox.setValue(var.getRef());
        refCell.appendChild(refTextbox);

        listbox.appendChild(li);
        new BindVariableCell(idTextbox, dsIdCombobox, despTextbox, refTextbox);

        return li;
    }
    private class BindVariableCell implements EventListener<Event> {

        private Textbox idTextbox;
        private Combobox dsIdCombobox;
        private Textbox despTextbox;
        private Textbox refTextbox;

        public BindVariableCell(Textbox idTextbox, Combobox dsIdCombobox, Textbox despTextbox, Textbox refTextbox) {
            this.idTextbox = idTextbox;
            this.idTextbox.addEventListener(Events.ON_CHANGE, this);
            this.dsIdCombobox = dsIdCombobox;
            this.dsIdCombobox.addEventListener(Events.ON_CHANGE, this);
            this.despTextbox = despTextbox;
            this.despTextbox.addEventListener(Events.ON_CHANGE, this);
            this.refTextbox = refTextbox;
            this.refTextbox.addEventListener(Events.ON_CHANGE, this);
        }

        @Override
        public void onEvent(Event event) throws Exception {
            Listitem listitem = (Listitem) idTextbox.getParent().getParent();
            final BindVariable index = listitem.getValue();
            if (event.getTarget().equals(idTextbox)) {
                isChange = true;
                index.setName(idTextbox.getValue().trim());
            } else if (event.getTarget().equals(dsIdCombobox)) {
                isChange = true;
                String valueStr = null;
                if (dsIdCombobox.getSelectedItem() != null)
                    valueStr = dsIdCombobox.getSelectedItem().getValue();
                index.setDsId(valueStr);
            } else if (event.getTarget().equals(despTextbox)) {
                isChange = true;
                index.setDesp(despTextbox.getValue().trim());
            } else if (event.getTarget().equals(refTextbox)) {
                isChange = true;
                index.setRef(refTextbox.getValue().trim());
            }
        }
    }
}
